#!/usr/bin/env zsh

indent="  "

# Ref: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1
function skip-crap {
    local datep="[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: "
    local crap_start="^${datep}Object [^ ]+ \(.*\), has been already finalized. Impossible to \w* any property \w* it.*"

    local crap_continue=(
        "^${datep}== Stack trace for context.*"
        "^${datep}#[0-9]+\s*0x.*"
    )

    local skip=0
    local skipped=0
    local begin_skip_date

    # Could probably be done more elegantly with awk/sed ?
    while IFS=$'\n' read -r line; do
        if [[ $line =~ $crap_start ]]; then
            # echo setting skip
            skip=1
            begin_skip=$line
            ((skipped += 1))
            continue
        fi

        if [[ $skip == 1 ]]; then
            if [[ ($line =~ $crap_continue[1]) ||
                      ($line =~ $crap_continue[2]) ]]; then
                ((skipped += 1))
                continue
            else
                # echo reset skip
                echo -E "$begin_skip"
                printf "${indent}... skipped \"already finalized\" crap ($skipped lines)\n"
                skip=0
                skipped=0
            fi
        fi

        echo -E "$line"
    done
}


# We use non-breaking space to encode newlines in multiline messages
function decode-multiline-message {
    stdbuf -oL sed -e 's| |\n    |g'
}

function gnome-shell-exe-path {
    if systemctl --user status gnome-shell-x11.service > /dev/null; then
        echo --user-unit=gnome-shell-x11.service
    elif systemctl --user status gnome-shell-wayland.service > /dev/null; then
        echo --user-unit=gnome-shell-wayland.service
    elif uname -a | grep --silent "NixOS"; then
        echo $(dirname =gnome-shell(:A))/.gnome-shell-wrapped
    else
        echo =gnome-shell
    fi
}

function procees {
    jq --unbuffered --raw-output '
       {ts: .__REALTIME_TIMESTAMP, message: .MESSAGE}
       | @sh "TS=\(.ts); MESSAGE=\(.message)\u0000"
    ' | while read -r -d $'\0' DATA; do
        eval $DATA

        TS=$((TS/1000000))

        PP_TS=$(date -d @${TS} +'%T')

        if [[ $MESSAGE == *$'\n'* ]]; then
            echo $PP_TS:
            echo -E $MESSAGE | sed 's/^/  /'
        else
            echo -E "$PP_TS: $MESSAGE"
        fi
    done

}

journalctl --follow --lines 400 -o json --output-fields MESSAGE \
           $@ $(gnome-shell-exe-path) \
    | procees \
    | skip-crap \
    | decode-multiline-message


